package com.joolun.mall.handle;

import club.mrxiao.common.error.ExpressError;
import club.mrxiao.common.error.ExpressErrorException;
import club.mrxiao.common.error.SfErrorMsgEnum;
import club.mrxiao.sf.bean.BaseResponse;
import club.mrxiao.sf.bean.BaseResultData;
import club.mrxiao.sf.bean.order.CargoDetail;
import club.mrxiao.sf.bean.order.ContactInfo;
import club.mrxiao.sf.bean.order.CreateOrderRequest;
import club.mrxiao.sf.util.json.SfGsonBuilder;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.google.common.collect.Maps;
import com.joolun.common.core.domain.AjaxResult;
import com.joolun.mall.dto.*;
import com.joolun.mall.entity.UserAddress;
import com.joolun.mall.express.CallExpressServiceTools;
import com.joolun.mall.express.HttpClientUtil;
import com.joolun.mall.express.IServiceCodeStandard;
import com.joolun.mall.express.code.ExpressServiceCodeEnum;
import com.joolun.mall.util.AddressUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author quyang
 * @description
 * @date 2022/1/9
 */
@Slf4j
public class SFLogisticsHandler extends LogisticsAbstractHandler {

    //顾客编码
    private static final String CLIENT_CODE = "LHBWLE8CL";
    //校验码
    private static final String CHECK_WORD = "FhfmaqSvYjAQLuzh0RJcm1elu3Kqx5n9";

    //沙箱环境的地址
    private static final String CALL_URL = "https://sfapi-sbox.sf-express.com/std/service";
    //生产环境的地址
    //private static final String CALL_URL = "https://sfapi.sf-express.com/std/service";

    //public void print() {
    //    ExpressServiceCodeEnum serviceCodeEnum = ExpressServiceCodeEnum.COM_RECE_CLOUD_PRINT_WAYBILLS;
    //
    //    CallExpressServiceTools client = CallExpressServiceTools.getInstance();
    //    Map<String, String> params = new HashMap<>();
    //    String timeStamp = String.valueOf(System.currentTimeMillis());
    //
    //    params.put("partnerID", CLIENT_CODE);
    //    params.put("requestID", UUID.randomUUID().toString().replace("-", ""));
    //    params.put("serviceCode", serviceCodeEnum.getCode());
    //    params.put("timestamp", timeStamp);
    //
    //    params.put("msgData", msgData);
    //    params.put("msgDigest", client.getMsgDigest(msgData, timeStamp, CHECK_WORD));
    //    String result = HttpClientUtil.post(CALL_URL, params);
    //
    //}

    @SneakyThrows
    @Override
    public List<JDFreightResultDTO> freight(UserAddress senderAddress, UserAddress receiverAddress, Integer weight) {
        IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_QUERY_DELIVERTM;
        Map<String, String> params = new HashMap<>();
        String timeStamp = String.valueOf(System.currentTimeMillis());
        SFFreightParamDTO paramDTO = new SFFreightParamDTO();
        //paramDTO.setBusinessType("6");
        paramDTO.setWeight(weight);
        paramDTO.setConsignedTime(DateUtil.now());
        paramDTO.setSearchPrice("1");
        SFDestAddressDTO senderAddr = new SFDestAddressDTO();
        senderAddr.setProvince(senderAddress.getProvinceName());
        senderAddr.setCity(senderAddress.getCityName());
        senderAddr.setDistrict(senderAddress.getCountyName());
        senderAddr.setAddress(AddressUtil.getFullAddressString(senderAddress));
        paramDTO.setSrcAddress(senderAddr);
        SFDestAddressDTO receiverAddr = new SFDestAddressDTO();
        receiverAddr.setProvince(receiverAddress.getProvinceName());
        receiverAddr.setCity(receiverAddress.getCityName());
        receiverAddr.setDistrict(receiverAddress.getCountyName());
        receiverAddr.setAddress(AddressUtil.getFullAddressString(receiverAddress));
        paramDTO.setDestAddress(receiverAddr);

        String msgData = JSON.toJSONString(paramDTO);
        params.put("partnerID", CLIENT_CODE);
        params.put("requestID", UUID.randomUUID().toString().replace("-", ""));
        params.put("serviceCode", standardService.getCode());
        params.put("timestamp", timeStamp);
        params.put("msgData", msgData);
        params.put("msgDigest", CallExpressServiceTools.getMsgDigest(msgData, timeStamp, CHECK_WORD));

        String result = HttpClientUtil.post(CALL_URL, params);
        SFBaseResultDTO<SFApiResultDataDTO<SFMsgDataDTO<SFDeliverTmDTO>>> resultDTO = JSON.parseObject(result.replaceAll("\\\\", "").replaceAll("\"[{]", "{").replaceAll("}\"", "}"), new TypeReference<SFBaseResultDTO<SFApiResultDataDTO<SFMsgDataDTO<SFDeliverTmDTO>>>>() {
        });
        if (SfErrorMsgEnum.CODE_A1000.getCode().equals(resultDTO.getApiResultCode())) {
            SFApiResultDataDTO<SFMsgDataDTO<SFDeliverTmDTO>> apiResultData = resultDTO.getApiResultData();
            if (apiResultData.getSuccess()) {
                List<SFDeliverTmDTO> deliverTmDTOList = apiResultData.getMsgData().getDeliverTmDto();
                return deliverTmDTOList.stream().map(m -> new JDFreightResultDTO(m.getBusinessType(), m.getBusinessTypeDesc(), m.getFee(), weight.toString(), m.getDeliverTime())).collect(Collectors.toList());
            }
        }
        return null;
    }

    @SneakyThrows
    @Override
    public AjaxResult delivery(UserAddress senderAddress, UserAddress receiverAddress, Integer weight, String orderId, String channelCode) {

        IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_CREATE_ORDER;
        Map<String, String> params = Maps.newHashMap();
        String timeStamp = String.valueOf(System.currentTimeMillis());
        String msgData = JSON.toJSONString(getParams(senderAddress, receiverAddress, weight, orderId));

        params.put("partnerID", CLIENT_CODE);
        params.put("requestID", UUID.randomUUID().toString().replace("-", ""));
        params.put("serviceCode", standardService.getCode());
        params.put("timestamp", timeStamp);
        params.put("msgData", msgData);
        params.put("msgDigest", CallExpressServiceTools.getMsgDigest(msgData, timeStamp, CHECK_WORD));

        String result = HttpClientUtil.post(CALL_URL, params);
        System.out.println("===返回结果：" + result);
        BaseResponse response = BaseResponse.fromJson(result);
        if (SfErrorMsgEnum.CODE_A1000.getCode().equals(response.getApiResultCode())) {
            BaseResultData data = BaseResultData.fromJson(response.getApiResultData());
            if (data.getSuccess()) {
                String jsonString = SfGsonBuilder.create().toJson(data.getMsgData());
                SFDeliverResultDTO deliverResultDTO = JSON.parseObject(jsonString, SFDeliverResultDTO.class);
                if (CollectionUtil.isNotEmpty(deliverResultDTO.getWaybillNoInfoList())) {
                    //WaybillType=1 母单
                    Optional<SFWaybillNoInfoListDTO> first = deliverResultDTO.getWaybillNoInfoList().stream().filter(m -> m.getWaybillType().equals(1)).findFirst();
                    if (first.isPresent()){
                        SFWaybillNoInfoListDTO sfWaybillNoInfoListDTO = first.get();
                        String waybillNo = sfWaybillNoInfoListDTO.getWaybillNo();
                        return AjaxResult.success((Object) waybillNo);
                    }
                }
            }
            throw new ExpressErrorException(ExpressError.builder()
                    .errorCode(data.getErrorCode())
                    .errorMsg(data.getErrorMsg())
                    .json(result)
                    .build());
        }
        return AjaxResult.error();
    }

    CreateOrderRequest getParams(UserAddress senderAddress, UserAddress receiverAddress, Integer weight, String orderId) {
        ContactInfo sender = new ContactInfo();
        sender.setCountry("CN");
        sender.setProvince(senderAddress.getProvinceName());
        sender.setCity(senderAddress.getCityName());
        sender.setCountry(senderAddress.getCountyName());
        sender.setAddress(AddressUtil.getFullAddressString(senderAddress));
        sender.setContactType(1);
        sender.setContact(senderAddress.getUserName());
        sender.setTel(senderAddress.getTelNum());

        ContactInfo receiver = new ContactInfo();
        receiver.setCountry("CN");
        receiver.setProvince(receiverAddress.getProvinceName());
        receiver.setCity(receiverAddress.getCityName());
        receiver.setCountry(receiverAddress.getCountyName());
        receiver.setAddress(AddressUtil.getFullAddressString(receiverAddress));
        receiver.setContactType(2);
        receiver.setContact(receiverAddress.getUserName());
        receiver.setTel(receiverAddress.getTelNum());


        List<ContactInfo> contactInfoList = new ArrayList<>();
        contactInfoList.add(sender);
        contactInfoList.add(receiver);


        CargoDetail cargoDetail = new CargoDetail();
        cargoDetail.setName("文件");
        cargoDetail.setCount(1);

        List<CargoDetail> cargoDetails = new ArrayList<>();
        cargoDetails.add(cargoDetail);

        CreateOrderRequest request = CreateOrderRequest.builder()
                .language("zh-CN")
                .orderId(orderId)
                .payMethod(1)
                .remark("测试订单")
                .contactInfoList(contactInfoList)
                .cargoDetails(cargoDetails)
                .totalWeight(weight.doubleValue())
                .build();

        return request;
    }

    @Override
    public JDCancelOrderResultDTO cancelOrder(String deliveryNo) {
        return super.cancelOrder(deliveryNo);
    }
}
